using System.Runtime.CompilerServices;
using SageKing.Designer.Core;
using SageKing.Designer.Core.Attributes; 
using SageKing.Designer.Core.Contracts;
using SageKing.Designer.Core.Models;
using JetBrains.Annotations;

namespace SageKing.Designer.Core.Activities;

/// <summary>
/// Iterate over a sequence of steps between a start and an end number.
/// </summary>
[Activity("SageKing", "Looping", "Iterate over a sequence of steps between a start and an end number.")]
[PublicAPI]
public class For : Activity
{
    private const string CurrentStepProperty = "CurrentStep";

    /// <inheritdoc />
    public For([CallerFilePath] string? source = default, [CallerLineNumber] int? line = default) : base(source, line)
    {
        
    }

    /// <inheritdoc />
    public For(int start, int end, int step, [CallerFilePath] string? source = default, [CallerLineNumber] int? line = default) : this(source, line)
    {
        Start = new Input<int>(start);
        End = new Input<int>(end);
        Step = new Input<int>(step);
    }

    /// <summary>
    /// The start step.
    /// </summary>
    [Input(Description = "The start step.")]
    public Input<int> Start { get; set; } = new(0);

    /// <summary>
    /// The end step.
    /// </summary>
    [Input(Description = "The end step.")]
    public Input<int> End { get; set; } = new(0);

    /// <summary>
    /// The step size. To count down, enter a negative number.
    /// </summary>
    [Input(Description = "The step size. To count down, enter a negative number.")]
    public Input<int> Step { get; set; } = new(1);

    /// <summary>
    /// Controls whether the end step is upper/lowerbound inclusive or exclusive. True (inclusive) by default.
    /// </summary>
    [Input(Description = "Controls whether the end step is upper/lowerbound inclusive or exclusive. True (inclusive) by default.")]
    public Input<bool> OuterBoundInclusive { get; set; } = new(true);

    /// <summary>
    /// The activity to execute for each iteration.
    /// </summary>
    [Port]
    public IActivity? Body { get; set; }

    /// <summary>
    /// Stores the current value for each iteration. 
    /// </summary>
    [Output]
    public Output<object?> CurrentValue { get; set; } = new(); 
}